import './FormTemp.scss'

import dayjs from 'dayjs'
import { useRequest } from 'alova/client'
import { useEffect, useState } from 'react'

import {
    AutoComplete,
    Button,
    Cascader,
    Form,
    Input,
    InputNumber,
    Select,
    DatePicker,
    TimePicker,
    TreeSelect,
    ColorPicker,
    Upload,
    Card,
    Collapse,
    Radio,
    Image
} from 'antd'

import { useMount, useThrottleFn, useDebounceFn } from 'ahooks'
import { InboxOutlined, CloseOutlined, PlusOutlined } from '@ant-design/icons'

import { Http } from '../Utils/Api'
import { ICONMapping } from '../Utils/IconMapping'
import { fromStore } from '../Config/zustand'

// import { ThemeColorMapping } from '../Config/config.jsx'
// import { formTempDateHandleBefore, getBase64 } from './Common'

const { TextArea } = Input

// 追加操作类型设置
export const FormTemplate = ({ columns, init, ChangeEvent, name, onSearch }) => {
    const { loading, updateFromData, updateFromLoad } = fromStore()

    const [form] = Form.useForm()
    const [uuid, setUuid] = useState()
    const [initialValues, setinitialValues] = useState()
    const [Columns, setColumns] = useState([])

    useMount(() => {
        if (init) {
            const initDate = JSON.parse(JSON.stringify(init))
            columns.forEach(({ valueType, dataIndex }) => {
                switch (valueType) {
                    case 'DatePicker':
                        if (initDate[dataIndex]) initDate[dataIndex] = dayjs(initDate[dataIndex])
                        break;
                    case 'TimePicker':
                        if (initDate[dataIndex]) initDate[dataIndex] = dayjs(initDate[dataIndex], 'HH:mm:ss')
                        break
                    default: break
                }
            })
            setUuid(initDate.uuid)
            setinitialValues(initDate)
            setColumns(columns.filter(v => !v.hideInModify))
        } else {
            setinitialValues({})
            setColumns(columns.filter(v => !v.hideInAdded))
        }
        updateFromLoad(false)
    })

    const { run } = useThrottleFn((e) => ChangeEvent.emit(e), { awit: 500 })
    if (ChangeEvent) Form.useWatch(run, form)

    // 提交函数
    const onFinish = (values) => {
        updateFromLoad(true)
        columns.forEach(({ valueType, dataIndex, picker, showTime, format }) => {
            switch (valueType) {
                case 'DatePicker':
                    values[dataIndex] = formTempDateHandleBefore({ picker, showTime, format }, values[dataIndex])
                    break;
                case 'TimePicker':
                    values[dataIndex] = dayjs(values[dataIndex]).format("HH:mm:ss")
                    break
                default: break
            }
        })
        updateFromData(values)
        // if (uuid) ModalEvent.emit({ type: 'Modify', data: values })
        // else ModalEvent.emit({ type: 'Added', data: values })
    }

    const onRefresh = () => {
        // ModalEvent.emit({ type: 'Refresh' })
        // form.resetFields()
    }

    // ModalEvent.useSubscription(val => {
    //     const { type, data } = val
    //     if (type === 'offLoading') setLoading(false)
    // })


    return (
        <div className='FormTemplate'>
            {initialValues &&
                <Form
                    form={form}
                    name={name || 'base'}
                    layout="vertical"
                    autoComplete="off"
                    className='FormTemp'
                    onFinish={onFinish}
                    initialValues={initialValues}
                >
                    {Columns.map((item, index) => <FormItemTemplate key={index} form={form} item={item} initialValues={initialValues} />)}
                    {onSearch ?
                        <div className='BtnSearch'>
                            <Button type="primary" htmlType="submit" size='large' >查询</Button>
                            <Button size='large' onClick={onRefresh} >重置</Button>
                        </div> :
                        <div className="BtnFormItem">
                            <Button type="primary" htmlType="submit" size='large' loading={loading}>提交数据</Button>
                        </div>
                    }
                </Form>
            }
        </div>
    );
};

export const ValueTypeMapping = [
    { label: '输入', value: 'Input' },
    { label: '富文本', value: 'TextArea' },
    { label: '密码', value: 'Password' },
    { label: '数字', value: 'InputNumber' },
    { label: '颜色', value: 'ColorPicker' },

    { label: '自动', value: 'AutoComplete' },
    { label: '单选', value: 'Radio' },
    { label: '下拉', value: 'Select' },

    { label: '联级', value: 'Cascader' },
    { label: '树形', value: 'TreeSelect' },

    { label: '日期', value: 'DatePicker' },
    { label: '时间', value: 'TimePicker' },

    { label: '上传', value: 'Upload' },

    { label: '图标', value: 'Icon' },
]


export const FormItemTemplate = ({ form, item, name, initialValues }) => {
    const { send: getOptions } = useRequest(({ url, params }) => Http({ url, params }), { immediate: false })
    const {
        valueType, title, dataIndex, rules, tooltip,
        valueEnum, fieldNames,
        valueJugde, valueApi, valueParams,
        picker, showTime, min, max,
        children, upLevel, judgeValue, judgeField
    } = item
    switch (valueType) {
        case 'Hidden':
            const HiddenTemp = () => {
                return (
                    <Form.Item
                        className='HiddenFormItem'
                        label={title}
                        name={name || name === 0 ? [name, dataIndex] : dataIndex}
                    >
                        <Input />
                    </Form.Item>
                )
            }
            return <HiddenTemp />
        case 'Input':
            const InputTemp = () => {
                return (
                    <Form.Item
                        className='TwoFormItem'
                        label={title}
                        name={name || name === 0 ? [name, dataIndex] : dataIndex}
                        tooltip={tooltip}
                        rules={[{ required: rules, message: '当前字段不得为空!' }]}
                    >
                        <Input placeholder={title} />
                    </Form.Item>
                )
            }
            if (judgeField) return (
                <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues[judgeField] !== currentValues[judgeField]}>
                    {({ getFieldValue }) => getFieldValue(judgeField) === judgeValue ? (<InputTemp />) : null}
                </Form.Item>)
            else return <InputTemp />
        case 'Password':
            const PasswordTemp = () => {
                return (
                    <Form.Item
                        className='TwoFormItem'
                        label={title}
                        name={name || name === 0 ? [name, dataIndex] : dataIndex}
                        tooltip={tooltip}
                        rules={[{ required: rules, message: '当前字段不得为空!' }]}
                    >
                        <Input.Password placeholder={title} />
                    </Form.Item>
                )
            }
            if (judgeField) return (
                <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues[judgeField] !== currentValues[judgeField]}>
                    {({ getFieldValue }) => getFieldValue(judgeField) === judgeValue ? (<PasswordTemp />) : null}
                </Form.Item>)
            else return <PasswordTemp />
        case 'AutoComplete':
            const AutoCompleteTemp = () => {
                const [autoCompleteResult, setAutoCompleteResult] = useState([])
                const onWebsiteChange = (value) => {
                    if (!value) setAutoCompleteResult([]);
                    else setAutoCompleteResult(['.com', '.org', '.net'].map((domain) => `${value}${domain}`))
                }
                const websiteOptions = autoCompleteResult.map((website) => ({ label: website, value: website }))
                return (
                    <Form.Item
                        className='TwoFormItem'
                        label={title}
                        name={name || name === 0 ? [name, dataIndex] : dataIndex}
                        tooltip={tooltip}
                        rules={[{ required: rules, message: '当前字段不得为空!' }]}
                    >
                        <AutoComplete options={websiteOptions} onChange={onWebsiteChange} placeholder={title} />
                    </Form.Item>
                )
            }
            if (judgeField) return (
                <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues[judgeField] !== currentValues[judgeField]}>
                    {({ getFieldValue }) => getFieldValue(judgeField) === judgeValue ? (<AutoCompleteTemp />) : null}
                </Form.Item>)
            else return <AutoCompleteTemp />
        case 'InputNumber':
            const InputNumberTemp = () => {
                return (
                    <Form.Item
                        className='TwoFormItem'
                        label={title}
                        name={name || name === 0 ? [name, dataIndex] : dataIndex}
                        tooltip={tooltip}
                        rules={[{ required: rules, message: '当前字段不得为空!' }]}
                    >
                        <InputNumber placeholder={title} min={min || null} max={max || null} />
                    </Form.Item>
                )
            }
            if (judgeField) return (
                <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues[judgeField] !== currentValues[judgeField]}>
                    {({ getFieldValue }) => getFieldValue(judgeField) === judgeValue ? (<InputNumberTemp />) : null}
                </Form.Item>)
            else return <InputNumberTemp />
        case 'Radio':
            const RadioTemp = () => {
                return (
                    <Form.Item
                        className='TwoFormItem'
                        label={title}
                        name={name || name === 0 ? [name, dataIndex] : dataIndex}
                        tooltip={tooltip}
                        rules={[{ required: rules, message: '当前字段不得为空!' }]}
                    >
                        <Radio.Group buttonStyle="solid">
                            {valueEnum.map(({ value, label }, index) => <Radio.Button key={index} value={value}>{label}</Radio.Button>)}
                        </Radio.Group>
                    </Form.Item>
                )
            }
            if (judgeField) return (
                <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues[judgeField] !== currentValues[judgeField]}>
                    {({ getFieldValue }) => getFieldValue(judgeField) === judgeValue ? (<RadioTemp />) : null}
                </Form.Item>)
            else return <RadioTemp />
        case 'Select':
            const SelectTemp = () => {
                const [Options, setOptions] = useState([])
                useMount(() => {
                    if (Array.isArray(valueEnum)) setOptions(valueEnum)
                    else setOptions(Object.keys(valueEnum).map((key) => ({ value: key, label: valueEnum[key].text || valueEnum[key] })))
                })
                return (
                    <Form.Item
                        className='TwoFormItem'
                        label={title}
                        name={name || name === 0 ? [name, dataIndex] : dataIndex}
                        tooltip={tooltip}
                        rules={[{ required: rules, message: '当前字段不得为空!' }]}
                    >
                        <Select
                            placeholder={title}
                            options={Options}
                            fieldNames={fieldNames}
                            allowClear
                            onClear={() => form.setFieldsValue({ [dataIndex]: undefined })}
                        />
                    </Form.Item>
                )
            }
            if (judgeField) return (
                <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues[judgeField] !== currentValues[judgeField]}>
                    {({ getFieldValue }) => getFieldValue(judgeField) === judgeValue ? (<SelectTemp />) : null}
                </Form.Item>)
            else return <SelectTemp />
        case 'SelectApi':
            const SelectApiTemp = () => {
                const nameValue = Form.useWatch(valueJugde, form)
                const [SelectApiOptions, setSelectApiOptions] = useState()

                const { run } = useDebounceFn(() => {
                    if (initialValues[valueJugde] !== nameValue) form.setFieldsValue({ [dataIndex]: undefined })
                    getOptions({ url: valueApi, params: { OrganizationUuid: nameValue, DataType: valueParams } }).then(res => setSelectApiOptions(res[valueParams]))
                }, { wait: 500 })

                useEffect(() => { run() }, [nameValue])
                return (
                    <Form.Item
                        className='TwoFormItem'
                        label={title}
                        name={name || name === 0 ? [name, dataIndex] : dataIndex}
                        tooltip={tooltip}
                        rules={[{ required: rules, message: '当前字段不得为空!' }]}
                    >
                        <Select placeholder={title} options={SelectApiOptions} fieldNames={fieldNames} />
                    </Form.Item>
                )
            }
            return <SelectApiTemp />
        case 'Cascader':
            const CascaderTemp = () => {
                return (
                    <Form.Item
                        className='TwoFormItem'
                        label={title}
                        name={name || name === 0 ? [name, dataIndex] : dataIndex}
                        tooltip={tooltip}
                        rules={[{ required: rules, message: '当前字段不得为空!' }]}
                    >
                        <Cascader
                            placeholder={title}
                            options={[{ value: 'xx', label: 'xx' }]}
                            allowClear
                        />
                    </Form.Item>
                )
            }
            if (judgeField) return (
                <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues[judgeField] !== currentValues[judgeField]}>
                    {({ getFieldValue }) => getFieldValue(judgeField) === judgeValue ? (<CascaderTemp />) : null}
                </Form.Item>)
            else return <CascaderTemp />
        case 'TreeSelect':
            const TreeSelectTemp = () => {
                return (
                    <Form.Item
                        className='TwoFormItem'
                        label={title}
                        name={name || name === 0 ? [name, dataIndex] : dataIndex}
                        tooltip={tooltip}
                        rules={[{ required: rules, message: '当前字段不得为空!' }]}
                    >
                        <TreeSelect
                            placeholder={title}
                            treeData={[{ value: 'xx', label: 'xx', },]}
                            allowClear
                        />
                    </Form.Item>
                )
            }
            if (judgeField) return (
                <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues[judgeField] !== currentValues[judgeField]}>
                    {({ getFieldValue }) => getFieldValue(judgeField) === judgeValue ? (<TreeSelectTemp />) : null}
                </Form.Item>)
            else return <TreeSelectTemp />
        case 'DatePicker':
            const DatePickerTemp = () => {
                return (
                    <Form.Item
                        className='TwoFormItem'
                        label={title}
                        name={name || name === 0 ? [name, dataIndex] : dataIndex}
                        tooltip={tooltip}
                        rules={[{ required: rules, message: '当前字段不得为空!' }]}
                    >
                        <DatePicker placeholder={title} picker={picker} showTime={showTime} />
                    </Form.Item>
                )
            }
            if (judgeField) return (
                <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues[judgeField] !== currentValues[judgeField]}>
                    {({ getFieldValue }) => getFieldValue(judgeField) === judgeValue ? (<DatePickerTemp />) : null}
                </Form.Item>)
            else return <DatePickerTemp />
        case 'TimePicker':
            const TimePickerTemp = () => {
                return (
                    <Form.Item
                        className='TwoFormItem'
                        label={title}
                        name={name || name === 0 ? [name, dataIndex] : dataIndex}
                        tooltip={tooltip}
                        rules={[{ required: rules, message: '当前字段不得为空!' }]}
                    >
                        <TimePicker placeholder={title} />
                    </Form.Item>
                )
            }
            if (judgeField) return (
                <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues[judgeField] !== currentValues[judgeField]}>
                    {({ getFieldValue }) => getFieldValue(judgeField) === judgeValue ? (<TimePickerTemp />) : null}
                </Form.Item>)
            else return <TimePickerTemp />
        case 'ColorPicker':
            const ColorPickerTemp = () => {
                return (
                    <Form.Item
                        className='TwoFormItem'
                        label={title}
                        name={name || name === 0 ? [name, dataIndex] : dataIndex}
                        tooltip={tooltip}
                        rules={[{ required: rules, message: '当前字段不得为空!' }]}
                    >
                        <ColorPicker
                            placeholder={title}
                            onChange={e => {
                                if (name || name === 0) {
                                    if (!form.getFieldValue(upLevel)[name]) form.getFieldValue(upLevel)[name] = {}
                                    form.getFieldValue(upLevel)[name][dataIndex] = e.toHexString()
                                } else {
                                    form.setFieldsValue({ [dataIndex]: e.toHexString() })
                                }
                            }}
                            presets={ThemeColorMapping}
                        />
                    </Form.Item>
                )
            }
            if (judgeField) return (
                <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues[judgeField] !== currentValues[judgeField]}>
                    {({ getFieldValue }) => getFieldValue(judgeField) === judgeValue ? (<ColorPickerTemp />) : null}
                </Form.Item>)
            else return <ColorPickerTemp />
        case 'TextArea':
            const TextAreaTemp = () => {
                return (
                    <Form.Item
                        className='OneFormItem'
                        label={title}
                        name={name || name === 0 ? [name, dataIndex] : dataIndex}
                        tooltip={tooltip}
                        rules={[{ required: rules, message: '当前字段不得为空!' }]}
                    >
                        <TextArea placeholder={title} autoSize={{ minRows: 3, maxRows: 5 }} />
                    </Form.Item>
                )
            }
            if (judgeField) return (
                <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues[judgeField] !== currentValues[judgeField]}>
                    {({ getFieldValue }) => getFieldValue(judgeField) === judgeValue ? (<TextAreaTemp />) : null}
                </Form.Item>)
            else return <TextAreaTemp />
        case 'Upload':
            const UploadTemp = () => {
                const normFile = (e) => {
                    console.log('Upload event:', e)
                    if (Array.isArray(e)) { return e }
                    return e?.fileList
                };
                const [previewOpen, setPreviewOpen] = useState(false);
                const [previewImage, setPreviewImage] = useState('');
                const [fileList, setFileList] = useState([
                    {
                        uid: '-1',
                        name: 'image.png',
                        status: 'done',
                        url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
                    },
                    {
                        uid: '-2',
                        name: 'image.png',
                        status: 'done',
                        url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
                    },
                    {
                        uid: '-3',
                        name: 'image.png',
                        status: 'done',
                        url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
                    },
                    {
                        uid: '-4',
                        name: 'image.png',
                        status: 'done',
                        url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
                    },
                    {
                        uid: '-xxx',
                        percent: 50,
                        name: 'image.png',
                        status: 'uploading',
                        url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
                    },
                    {
                        uid: '-5',
                        name: 'image.png',
                        status: 'error',
                    },
                ]);
                const handlePreview = async (file) => {
                    if (!file.url && !file.preview) {
                        file.preview = await getBase64(file.originFileObj);
                    }
                    setPreviewImage(file.url || file.preview);
                    setPreviewOpen(true)
                };
                const handleChange = ({ fileList: newFileList }) => setFileList(newFileList);
                const uploadButton = (
                    <button style={{ border: 0, background: 'none' }} type="button">
                        <PlusOutlined />
                        <div style={{ marginTop: 8 }}>Upload</div>
                    </button>
                )

                return (
                    <Form.Item
                        className='OneFormItem'
                        label={title}
                        name={name || name === 0 ? [name, dataIndex] : dataIndex}
                        tooltip={tooltip}
                        rules={[{ required: rules, message: '当前字段不得为空!' }]}
                    >
                        <Form.Item
                            noStyle
                            name={name || name === 0 ? [name, dataIndex] : dataIndex}
                            valuePropName="fileList"
                            getValueFromEvent={normFile}
                        >
                            <div>
                                <Upload
                                    action="https://660d2bd96ddfa2943b33731c.mockapi.io/api/upload"
                                    listType="picture-card"
                                    fileList={fileList}
                                    onPreview={handlePreview}
                                    onChange={handleChange}
                                >
                                    {fileList.length >= 8 ? null : uploadButton}
                                </Upload>
                                {previewImage && (
                                    <Image
                                        wrapperStyle={{ display: 'none' }}
                                        preview={{
                                            visible: previewOpen,
                                            onVisibleChange: (visible) => setPreviewOpen(visible),
                                            afterOpenChange: (visible) => !visible && setPreviewImage(''),
                                        }}
                                        src={previewImage}
                                    />
                                )}
                            </div>
                            {/* <Upload.Dragger name="files" action="/upload.do">
                                <p className="ant-upload-drag-icon"><InboxOutlined /></p>
                                <p className="ant-upload-text">单击或拖动文件到此区域进行上传</p>
                                <p className="ant-upload-hint">支持单次或批量上传。</p>
                            </Upload.Dragger> */}

                        </Form.Item>
                    </Form.Item>
                )
            }
            if (judgeField) return (
                <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues[judgeField] !== currentValues[judgeField]}>
                    {({ getFieldValue }) => getFieldValue(judgeField) === judgeValue ? (<UploadTemp />) : null}
                </Form.Item>)
            else return <UploadTemp />
        case 'Fields':
            const FieldsTemp = () => {
                return (
                    <Form.List name={dataIndex}>
                        {(fields, { add, remove }) => {
                            return (
                                <>
                                    {fields.map(({ key, name }) => (
                                        <Card
                                            key={key}
                                            className='FormList'
                                            title={`${title} ${name + 1}`}
                                            extra={
                                                (!min || fields.length > min) &&
                                                <CloseOutlined onClick={() => remove(name)} />
                                            }
                                        >
                                            {children.map((item, index) => <FormItemTemplate key={index} form={form} item={item} name={name} />)}
                                        </Card>
                                    ))}
                                    {max && fields.length < max &&
                                        <Button type="dashed" style={{ marginBottom: 16 }} onClick={() => add()} block>+ 追加分组</Button>
                                    }
                                </>
                            )
                        }}

                    </Form.List>
                )
            }
            if (judgeField) return (
                <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues[judgeField] !== currentValues[judgeField]}>
                    {({ getFieldValue }) => getFieldValue(judgeField) === judgeValue ? (<FieldsTemp />) : null}
                </Form.Item>)
            else return <FieldsTemp />
        case 'Collapse':
            const CollapseTemp = () => {
                const CollapseItemsTemp = () => {
                    return <div>{children.map((item, index) => <FormItemTemplate key={index} form={form} item={item} name={name} />)}</div>
                }
                const items = [{ key: 1, label: title, children: <CollapseItemsTemp /> }]
                return (
                    <Collapse items={items} defaultActiveKey={1} />
                )
            }
            if (judgeField) return (
                <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues[judgeField] !== currentValues[judgeField]}>
                    {({ getFieldValue }) => getFieldValue(judgeField) === judgeValue ? (<CollapseTemp />) : null}
                </Form.Item>)
            else return <CollapseTemp />
        case 'Icon':
            const IconTemp = () => {
                const [IconActive, setIconActive] = useState()
                const onClick = (e) => {
                    if (name || name === 0) {
                        if (!form.getFieldValue(upLevel)[name]) form.getFieldValue(upLevel)[name] = {}
                        form.getFieldValue(upLevel)[name][dataIndex] = e
                    }
                    else form.setFieldsValue({ [dataIndex]: e })
                    setIconActive(e)
                }
                useMount(() => {
                    if (name || name === 0) setIconActive(form.getFieldValue([upLevel, name, dataIndex]) || 'FullscreenExitOutlined')
                    else setIconActive(form.getFieldValue(dataIndex) || 'FullscreenExitOutlined')
                })
                return (
                    <Form.Item
                        className='OneFormItem'
                        name={name || name === 0 ? [name, dataIndex] : dataIndex}
                        label={title}
                        tooltip={tooltip}
                        rules={[{ required: rules, message: '当前字段不得为空!' }]}
                    >
                        {IconActive ?
                            <div className='SelectIconBox'>
                                {Object.keys(ICONMapping).map(key =>
                                    <div className={IconActive === key ? 'active' : ''} onClick={() => onClick(key)} key={key}>{ICONMapping[key]}</div>
                                )}
                            </div> :
                            <Input style={{ display: 'none' }} />
                        }
                    </Form.Item>
                )
            }
            if (judgeField) return (
                <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues[judgeField] !== currentValues[judgeField]}>
                    {({ getFieldValue }) => getFieldValue(judgeField) === judgeValue ? (<IconTemp />) : null}
                </Form.Item>)
            else return <IconTemp />
        default:
            return <div className='NonFormItem'>未知组件 {valueType}: 请联系管理员</div>
    }
}



